package com.fishery.authority.service.impl;

import com.fishery.authority.service.CaptchaService;
import com.fishery.authority.utils.IpAddressUtil;
import com.fishery.entity.Result;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 白sa能
 * @className
 * @date Created in 4:31 PM 1/16/21
 * @package com.fishery.ucenter.service.impl
 * @Description
 */
@Service
public class CaptchaServiceImpl implements CaptchaService {

    @Value("${captcha.timeout}")
    private Integer timeout;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired(required = false)
    DefaultKaptcha producer;

    /**
     * 生成验证码
     *
     * @param ipAddress
     * @return
     * @throws IOException
     */
    @Override
    public Map<String, Object> createVerificationCode(String ipAddress) throws IOException {
        // 先删除redis中已有的验证码
        deleteVerificationCode(ipAddress);
        Map<String, Object> map = new HashMap<>();
        // 生成文字验证码
        String text = producer.createText().toLowerCase();
        // 生成图片验证码
        BufferedImage image = producer.createImage(text);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(image, "jpg", outputStream);

        map.put("img", Base64.getEncoder().encodeToString(outputStream.toByteArray()));
        // 以ip为key  验证码为value存在redis中
        redisTemplate.opsForValue().set("verificationCode_ip_" + ipAddress, text, timeout, TimeUnit.MINUTES);

        return map;
    }

    /**
     * 删除验证码
     *
     * @param ipAddress
     * @return
     */
    @Override
    public Result deleteVerificationCode(String ipAddress) {
        if(redisTemplate.delete("verificationCode_ip_"+ipAddress)) {
            return Result.success();
        } else {
            return Result.error();
        }
    }

    /**
     * 修改验证码
     *
     * @param request
     * @param phone
     * @return
     */
    @Override
    public Result changeVerificationCode(HttpServletRequest request, String phone) {
        if (StringUtils.isEmpty(phone)) {
            return Result.error();
        }
        // 用户的ip地址
        String ipAdrress = IpAddressUtil.getIpAdrress(request);
        // 获取redis中的验证码
        String codeInRedis = (String) redisTemplate.opsForValue().get("verificationCode_ip_" + ipAdrress);
        // 删除redis中的验证码，使验证码具有一次性
        deleteVerificationCode(ipAdrress);
        if(phone.equalsIgnoreCase(codeInRedis)) {
            return Result.success();
        } else {
            return Result.error();
        }
    }

    /**
     * 检查验证码
     *
     * @param request
     * @param userVerificationCode
     * @return
     */
    @Override
    public boolean checkVerificationCode(HttpServletRequest request, String userVerificationCode) {
        if (StringUtils.isEmpty(userVerificationCode)) {
            return false;
        }
        // 用户的ip地址
        String ipAdrress = IpAddressUtil.getIpAdrress(request);
        // 获取redis中的验证码
        String codeInRedis = (String) redisTemplate.opsForValue().get("verificationCode_ip_" + ipAdrress);
        // 删除redis中的验证码，使验证码具有一次性
        deleteVerificationCode(ipAdrress);
        return userVerificationCode.equalsIgnoreCase(codeInRedis);
    }
}